package com.lenovo.nova.widget;


import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ScrollView;

import com.lenovo.nova.util.Applications;
import com.lenovo.nova.util.Applications.OnInputModeChangeListener;
import com.lenovo.nova.util.debug.slog;
import com.lenovo.nova.widget.windowmanager.WindowManagerArrow;

public class CustomScrollView extends ScrollView implements OnGlobalLayoutListener , OnInputModeChangeListener{

	private int mLimitHeight = -1;
	private int childHeight = 0;
	private OnScrollStopListner onScrollstopListner;
	private OnScrollStopListner defaultOnScrollstopListner;
	public static final int ARROW_DOWN = 0;
	public static final int ARROW_UP = 1;
	private static final String TAG = "CustomScrollView";
	private int mChildTotalHeight = 0;
	private boolean mCanFling = false;
	private static int ARROW_OFFSET = -35;

	public interface OnScrollStopListner {
		void onScrollToTopEdge();

		void onScrollToMiddle();

		void onScrollToBottomEdge();

		void onScrollStoped();
	}

	public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public CustomScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public CustomScrollView(Context context) {
		super(context);
	}

	public void setLimitHeight(int limit) {
		mLimitHeight = limit;
	}
	int mType = Integer.MAX_VALUE;
	public void setArrowType(int flag){
		mType = flag;
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int height = MeasureSpec.getSize(heightMeasureSpec);
		if (mLimitHeight > 0 && height > mLimitHeight) {
			heightMeasureSpec = MeasureSpec.makeMeasureSpec(mLimitHeight,
					MeasureSpec.getMode(heightMeasureSpec));
		}
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

    public void setOnScrollStopListner(OnScrollStopListner listner) {
		onScrollstopListner = listner;
	}

	private void checkTotalHeight() {
		childHeight = 0;
		for (int i = 0; i < getChildCount(); i++) {
			childHeight += getChildAt(i).getHeight();
		}
		slog.p(TAG,"checkTotalHeight getChildCount " +getChildCount() + "  childHeight " + childHeight + "  getPaddingTop  getPaddingBottom " +  getPaddingTop() + "  "
				+ getPaddingBottom() + "  getHeight " + getHeight() );
		mCanFling = (childHeight +  getPaddingTop() + getPaddingBottom()) > getHeight();
	}
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		checkTotalHeight();
		Rect outRect = new Rect();
		getDrawingRect(outRect);
		OnScrollStopListner actionScrollListener = (onScrollstopListner != null) ? onScrollstopListner : defaultOnScrollstopListner;
		actionScrollListener.onScrollStoped();
		slog.p(TAG,"onScrollChanged  l " + l + " t " + t + " oldL " + oldl + " oldt " + oldt + " outRect.bottom " + outRect.bottom );
			if(t == 0) {
				actionScrollListener.onScrollToTopEdge();
			} else if (childHeight + getPaddingTop()
					+ getPaddingBottom() == outRect.bottom) {
				actionScrollListener.onScrollToBottomEdge();
			} else {
				actionScrollListener.onScrollToMiddle();
			}
		super.onScrollChanged(l, t, oldl, oldt) ;
	}

	@Override
	public void onGlobalLayout() {
		slog.p(TAG,"onGlobalLayout " + getContext());
		int[] location = new int[2];
		getLocationOnScreen(location);
		checkTotalHeight();
		int childTotalHeight = childHeight +  getPaddingTop() + getPaddingBottom();
		if(getHeight() > 0 && childTotalHeight > 0 && getWindowVisibility() == View.VISIBLE)
		initArrow(getHeight(),childTotalHeight);
	}
	
	WindowManagerArrow arrow = null;
	private void initArrow(int height,int childTotalHeight) {
		slog.p(TAG,"initArrow arrow " + arrow + " childTotalHeight " + childTotalHeight + " mChildTotalHeight " + mChildTotalHeight +
				" mCanFling " + mCanFling);
		if(arrow != null){
			if(childTotalHeight != mChildTotalHeight) {
				if(mCanFling) {//
					arrow.setTopVisible(false);
					arrow.setBottomVisible(true);
				} else {
					arrow.setTopVisible(false);
					arrow.setBottomVisible(false);
				}
				mChildTotalHeight = childTotalHeight; 
			}
			int[] location = new int[2];
			getLocationOnScreen(location);
			int topY =  location[1] - arrow.getTopImageViewHeight() ;
			arrow.showArrowYPosition(topY - ARROW_OFFSET, location[1] + height + ARROW_OFFSET);

			int imageX = location[0] + (getWidth() - arrow.getTopImageViewWidth()) / 2;
			arrow.showArrowXPosition(imageX);
		}
	}
	
	@Override
	protected void onAttachedToWindow() {
		Applications.get().addOnInputModeChangeListener(this);
		initArrow();
		slog.p(TAG,"onAttachedToWindow " + mType);
		if(mType != Integer.MAX_VALUE){
			arrow.setParamType(mType);
		}
		getViewTreeObserver().addOnGlobalLayoutListener(this);
		defaultOnScrollstopListner = new OnScrollStopListner() {
			
			@Override
			public void onScrollToTopEdge() {
				slog.p(TAG,"onScrollToTopEdge onScrollToTopEdge " + mCanFling);
				if(arrow != null && mCanFling) {
					setArrowShowBottom();
				}
			}
			@Override
			public void onScrollToMiddle() {
				if(arrow != null && mCanFling) {
					setArrowTwoShow();
				}
			}
			
			@Override
			public void onScrollToBottomEdge() {
				slog.p(TAG,"onScrollToBottomEdge mCanFling " + mCanFling);
				if(arrow != null && mCanFling) {
					setArrowTopShow();
				}
			}
			
			@Override
			public void onScrollStoped() {
			}
		};
		super.onAttachedToWindow();
	}

	private void setArrowTopShow() {
		arrow.setTopVisible(true);
		arrow.setBottomVisible(false);
	}
	
	private void setArrowTwoShow() {
		arrow.setTopVisible(true);
		arrow.setBottomVisible(true);
	}
	
	private void setArrowShowBottom() {
		arrow.setTopVisible(false);
		arrow.setBottomVisible(true);
	}
	
	private void initArrow() {
		if(arrow == null){
			arrow = new WindowManagerArrow(getContext(),false) {
				public void onClick(View v) {
					if (v == mTopView) {
						arrow(ARROW_DOWN);
					} else if (v == mBottomView) {
						arrow(ARROW_UP);
					}
				};
			};
		}
	}
	
	@Override
	protected void onDetachedFromWindow() {
		Applications.get().removeOnInputChangeListener(this);
		arrow.close();
		super.onDetachedFromWindow();
	}
	public void arrow(int direction) {
		switch (direction) {
		case ARROW_DOWN:
//			scrollBy(0,(int)mContext.getResources().getDimension(R.dimen.home_button_sliding_up_Y));
			break;
		case ARROW_UP:
//			scrollBy(0, (int)mContext.getResources().getDimension(R.dimen.home_button_sliding_down_Y));
			break;
		default:
			break;
		}
	}

	@Override
	public void onInputModeChange(boolean isInTouchMode) {
		if(!isInTouchMode){
			requestFocus();
		}
	}

}
